/*
 * By: Werner Schuster (murphee)
 * 
 * Copyright (c) 2005-2006 Werner Schuster (murphee)
 * 
 * This file is part of the EclipseShell project. EclipseShell is subject 
 * to the Eclipse Public License (EPL) available at
 * http://www.eclipse.org/org/documents/epl-v10.php
 * or in the file /epl-v10.html in the source for other info
 * see the /eclipseshell.license file
 */
package net.sf.eclipseshell.extensions;

import java.io.OutputStream;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

import net.sf.eclipseshell.internal.extensions.ExecutionProviderManager;

import org.eclipse.core.resources.IResource;

/**
 * Manages the launches of ExecutionEnvironments in the system. 
 * This class can be used to launch new instances of ExecutionEnvironments,
 * get the list of launched ExecutionEnvironments and the list of
 * registered ExecutionEnvironments.
 * 
 * @author murphee
 *
 */
public class ExecutionEnvironmentLaunchManager {
	static Map launchedEnvironments_ = new WeakHashMap();
	
	/**
	 * 
	 * @param id the ID of the provider, this is the id from the extension point in the providers plugin.xml, must NOT be null
	 * @param mode the launch mode, must NOT be null
	 * @param output OutputStream where the environment output is sent, must NOT be null
	 * @param file a file where the that allows the environment to find the workspace it's running in. Important; this can be null.  
	 * @return an IExecutionEnvironment  or null if none could be created for the given parameters
	 */
	public static IExecutionEnvironment launch(String id, String mode, OutputStream output, IResource file){
		IExecutionEnvironmentProvider prov = ExecutionProviderManager.getProviderById(id);
		if(prov != null){
			return launch(prov, mode, output, file);
		}
		return null;
	}
	
	/**
	 * Returns an array of @see IExecutionEnvironmentProvider that describe the installed
	 * ExecutionEnvironmentProviders.
	 * 
	 */
	public static IExecutionProviderHandle[] getRegisteredProviders(){
		return ExecutionProviderManager.getAllProviders();
	}
	
	/**
	 * Adds a new  IExecutionEnvironmentProvider to the provider list.
	 * 
	 * @param handle descriptor for the provider, NOT null
	 * @param prov the provider object, NOT null
	 */
	public static void addExecutionEnvironmentProvider(IExecutionProviderHandle handle, IExecutionEnvironmentProvider prov){
		ExecutionProviderManager.addProvider(handle, prov);
	}

	public static IExecutionEnvironment launch(IExecutionEnvironmentProvider prov, String mode, OutputStream output, IResource file) {
		if(prov != null){
			IExecutionEnvironment tempEnv = prov.createNew(file, output, mode);
			launchedEnvironments_.put(tempEnv, null);
			return tempEnv;
		}
		return null;
	}
	
	public static Set getAllActiveExecutionEnvironments(){
		Set retValue = new HashSet(launchedEnvironments_.keySet());
		IExecutionProviderHandle[] registeredProviders = getRegisteredProviders();
		for (int i = 0; i < registeredProviders.length; i++) {
			IExecutionProviderHandle currProviderHandle = registeredProviders[i];
			IExecutionEnvironmentProvider provider = ExecutionProviderManager.getProviderById(currProviderHandle.getId());
			IExecutionEnvironment[] possibleExecutionEnvironments = provider.getPossibleExecutionEnvironments();
			if(possibleExecutionEnvironments != null){
				for (int j = 0; j < possibleExecutionEnvironments.length; j++) {
					IExecutionEnvironment currEnvironment = possibleExecutionEnvironments[j];
					retValue.add(currEnvironment);
				}
			}
			
		}
		return retValue;
	}

	public static void shutdown(IExecutionEnvironment provider) {
		if(launchedEnvironments_.containsKey(provider)){
			provider.shutdown();
			launchedEnvironments_.remove(provider);
		}		
	}
	

}
